﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class StretchArrow : MonoBehaviour {

    [System.Serializable]
    public class Model
    {
        public float[] factor = new float[5];

        public delegate void SetFactorSignal(int index, float initFactor, float curFactor);

        public SetFactorSignal setFactorSignal;

        public void SetFactor(int index, float curFactor)
        {
            float initFactor = factor[index];
            factor[index] = curFactor;
            if (setFactorSignal != null) setFactorSignal(index, initFactor, curFactor);
        }
    }

    public Model model = null;

    public Transform[] pivot;
    public Transform[] pivotArrow;
    public Transform center;
    void Start()
    {
        //set out-let setting
        List<Transform> pivot = new List<Transform>();
        List<Transform> arrow = new List<Transform>();
        foreach (Transform child in transform)
        {
            if (child.name.StartsWith("center")) center = child;
            if (child.name.StartsWith("pivot")) pivot.Add(child);
            if (child.name.StartsWith("arrow")) arrow.Add(child);
        }

        this.pivot = pivot.OrderBy(t => int.Parse(t.name.Split("_"[0])[1])).ToArray();
        this.pivotArrow = arrow.OrderBy(t => int.Parse(t.name.Split("_"[0])[1])).ToArray();


        ///Init Model
        this.model = new Model();
        this.model.setFactorSignal += On_SetFactorSignal;

        for (int i = 0; i < 5; i++)
        {
            this.model.SetFactor(i,0.5f);
        }
    }

    #region Controller
    void OnGUI()
    {
        for (int i = 0; i < 5; i++)
        {
            float tmp = GUI.HorizontalSlider(
                new Rect(25, 25 + 70 * i, 100, 50), this.model.factor[i], 0.0F, 1.0F);
            if (tmp != this.model.factor[i])
            {
                this.model.SetFactor(i, tmp);
            }
            
        }
    }
    #endregion

    #region View
    public void On_SetFactorSignal(int index, float initFactor, float curFactor) 
    {
        Transform curPivot = this.pivot[index];
        //Debug.Log(curPivot.transform.name);
        //Debug.Log(" curFactor " + curFactor);

        Transform selfArrow = this.pivotArrow[index];

        int nextIndex = (index >= (this.pivot.Length - 1) ? 0 : index + 1);
        Transform nextPivot = this.pivot[nextIndex];

        Vector3 start = Sample(this.center.transform.localPosition, curPivot.transform.localPosition, curFactor);
        Vector3 end = Sample(this.center.transform.localPosition, nextPivot.transform.localPosition, this.model.factor[nextIndex]);
        //set selfArrow pos and rotation
        SetCurArrowPos(selfArrow.gameObject, start, end);
        SetRotation(selfArrow.gameObject, start, end);

        int preIndex = (index <= 0 ? 4 : index - 1);
        Transform prePivot = this.pivot[preIndex];
        Transform preArrow = this.pivotArrow[preIndex];

        //set preArrow rotation
        start = Sample(this.center.transform.localPosition, prePivot.transform.localPosition, this.model.factor[preIndex]);
        end = Sample(this.center.transform.localPosition, curPivot.transform.localPosition, curFactor);
        SetRotation(preArrow.gameObject, start, end);
    }

    public void SetCurArrowPos(GameObject arrow, Vector3 start, Vector3 end)
    {
        arrow.transform.localPosition = start;
    }

    public void SetRotation(GameObject arrow, Vector3 start, Vector3 end)
    {
        arrow.GetComponent<UIWidget>().width = (int)Vector3.Distance(start, end);

        arrow.transform.localRotation = Quaternion.FromToRotation(Vector3.right, (end - start).normalized);
    }

    public Vector3 Sample(Vector3 start, Vector3 end, float factor)
    {
        return Vector3.Lerp(start, end, factor);
    }
    #endregion
}
